# dbplugs/infoitem.py
#
#
#

""" information items """

__copyright__ = 'this file is in the public domain'

from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.redispatcher import rebefore, reafter
from gozerbot.aliases import aliases
from gozerbot.plughelp import plughelp
from gozerbot.db import db
import _mysql_exceptions
import time, re

plughelp.add('infoitem', 'also known as factoids .. info can be retrieved \
by keyword or searched')

class Infoitems(object):

    """ information items """
 
    def add(self, item, description, userhost, ttime):
        """ add an item """
        item = item.lower()
        result = db.execute(""" INSERT INTO infoitems(item, description, \
userhost, time) VALUES(%s, %s, %s, %s) """, (item, description, \
userhost, ttime))
        return result

    def get(self, item):
        """ get infoitems """
        item = item.lower()
        result = db.execute(""" SELECT indx, item, description FROM \
infoitems WHERE item = %s """, item)
        return result

    def delete(self, indexnr):
        """ delete item with indexnr  """
        result = db.execute(""" DELETE FROM infoitems WHERE indx = %s """, \
indexnr)
        return result

    def deltxt(self, item, txt):
        """ delete item with matching txt """
        result = db.execute(""" DELETE FROM infoitems WHERE item = %s AND \
description LIKE %s LIMIT 1""", (item, '%%%s%%' % txt))
        return result

    def size(self):
        """ return number of items """
        result = db.execute(""" SELECT COUNT(*) FROM infoitems """)
        return result[0][0]

    def searchitem(self, search):
        """ search items """
        result = db.execute(""" SELECT indx, item, description \
FROM infoitems WHERE item REGEXP %s """, search)
        return result

    def searchdescr(self, search):
        """ search descriptions """
        search = re.escape(search)
        result = db.execute(""" SELECT indx, item, description \
FROM infoitems WHERE description REGEXP %s """, search)
        return result

info = Infoitems()

def handle_infosize(bot, ievent):
    """ info-size .. show number of information items """
    ievent.reply("we have %s infoitems" % info.size())

cmnds.add('info-size', handle_infosize, ['USER', 'WEB'])
examples.add('info-size', 'show number of infoitems', 'info-size')

def handle_addinfoitem(bot, ievent, groups):
    """ <item> = <description> .. add information item """
    try:
        (what, description) = groups
    except ValueError:
        ievent.missing('<item> <description>')
        return
    if len(description) < 3:
        ievent.reply('i need at least 3 chars for the description')
        return
    result = info.add(what, description, ievent.userhost, time.time())
    if result:
        ievent.reply('%s added' % what)
    else:
        ievent.reply('add failed')

rebefore.add(10, '^(.+?)\s+=\s+(.+)$', handle_addinfoitem, 'USER')
examples.add('=', 'add description to item', 'dunk = top')

def handle_question(bot, ievent, groups):
    """ <item> ? .. ask for information item """
    try:
        item = groups[0]
    except IndexError:
        ievent.reply('i need a argument')
        return
    item = item.strip().lower()
    result = info.get(item)
    if result:
        res = ""
        for i in result:
            res += '%s .. ' % i[2]
        else:
            ievent.reply(res[:-4])
    else:
        ievent.reply('no %s found' % item)

reafter.add(10, '^(.+)\?$', handle_question, ['USER', 'WEB'])
reafter.add(10, '^\?(.+)$', handle_question, ['USER', 'WEB'])
examples.add('?', 'show infoitems of <what>', '1) test? 2) ?test')

def handle_forget(bot, ievent):
    """ info-forget <item> <txttomatch> .. remove information item """
    if len(ievent.args) == 1:
        ievent.missing('<item> <txttomatch> (min 3 chars)')
        return
    try:
        what = ' '.join(ievent.args[:-1])
        txt = ievent.args[-1]
    except (ValueError, IndexError):
        ievent.missing('<item> <txttomatch> (min 3 chars)')
        return
    if len(txt) < 3:
        ievent.reply('i need a mask with at least 3 characters')
        return
    what = what.strip().lower()
    try:
        print what, txt
        nritems = info.deltxt(what, txt)
        if nritems:
            ievent.reply('item deleted')
        else:
            ievent.reply('delete %s of %s failed' % (txt, what))
    except Exception, ex:
        ievent.reply('ERROR: %s' % str(ex))

cmnds.add('info-forget', handle_forget, ['FORGET', 'OPER'])
examples.add('info-forget', 'info-forget <item> <txt> .. forget <item> \
containing <txt>', 'info-forget dunk bla')
aliases.data['forget'] = 'info-forget'

def handle_searchinfo(bot, ievent):
    """ info-si <txt> .. search information items keys """
    if not ievent.rest:
        ievent.missing('<txt>')
        return
    else:
        what = ievent.rest
    what = what.strip().lower()
    try:
        result = info.searchitem(what)
    except _mysql_exceptions.OperationalError:
        ievent.reply("can't make RE out of %s" % what)
        return
    if result:
        res = ""
        for i in result:
            res += "[%s] %s .. " % (i[1], i[2])
        ievent.reply(res[:-4])
    else:
        ievent.reply('none found')

cmnds.add('info-si', handle_searchinfo, ['USER', 'WEB'])
examples.add('info-si', 'info-si <txt> .. search the infoitems keys', \
'info-si test')
aliases.data['si'] = 'info-si'

def handle_searchdescr(bot, ievent):
    """ info-sd <txt> .. search information descriptions """
    if not ievent.rest:
        ievent.missing('<txt>')
        return
    else:
        what = ievent.rest
    what = what.strip().lower()
    try:
        result = info.searchdescr(what)
    except _mysql_exceptions.OperationalError:
        ievent.reply("can't make RE out of %s" % what)
        return
    if result:
        res = ""
        for i in result:
            res += "[%s] %s .. " % (i[1], i[2])
        ievent.reply(res[:-4])
    else:
        ievent.reply('none found')

cmnds.add('info-sd', handle_searchdescr, ['USER', 'WEB'])
examples.add('info-sd', 'info-sd <txt> ..  search description of infoitems', \
'info-sd http')
aliases.data['sd'] = 'info-sd'
aliases.data['sl'] = 'info-sd'
